<script setup lang="ts">
import {ref, computed, watch, defineProps, defineEmits} from 'vue'
import {ElMessage, FormInstance} from 'element-plus'
import {getShipDataRecord, getShipDataCompare} from "@/services/data";
import * as echarts from 'echarts'


// ----- Props / Emits -----
const props = defineProps<{
  /** 对话框显隐 */
  modelValue: boolean
  /** 控制哪些行可选（配合表格 selection 的 selectable 回调） */
  rowSelectable?: (row: any, index: number) => boolean
  /** 外部传入：当前图表的横/纵摇数据（可选携带时间戳 ts） */
  predicted?: {
    roll: { x: string[]; y: number[]; ts?: Array<string | number> }
    pitch: { x: string[]; y: number[]; ts?: Array<string | number> }
  }
}>()

const emits = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
  (e: 'cancel'): void
  (e: 'compare', payload: { id: string | number, start: string, end: string }): void
}>()

// ----- Local state -----
const innerVisible = computed({
  get: () => props.modelValue,
  set: (v: boolean) => emits('update:modelValue', v)
})

const filters = ref({
  name: '',
  page: 1,
  length: 10,
})

let total = 0
let dataList = ref([])

const tableRef = ref()
const selectableFn = computed(() => props.rowSelectable ?? (() => true))

const selectedId = ref<string | number | ''>('')
const selectedRow = ref<any | null>(null)

// 对比时段
const start = ref<string>('')
const end = ref<string>('')

const compareVisible = ref(false)
const compareLoading = ref(false)
const metricOptions = [
  {label: '横摇', value: 'roll'},
  {label: '纵摇', value: 'pitch'}
] as const
const chartRef = ref<HTMLDivElement | null>(null)
let chart: echarts.ECharts | null = null

// 缓存接口返回（避免切换横/纵摇重复拉取）
const apiSeries = ref<{ times: number[]; roll: number[]; pitch: number[] }>({
  times: [], roll: [], pitch: []
})

function toEpoch(v: any): number {
  if (typeof v === 'number') return v
  const t = new Date(v).getTime()
  return isNaN(t) ? 0 : t
}

function renderChart() {
  if (!chartRef.value) return
  nextTickInitChart()
  const times = apiSeries.value.times
  if (!times.length) {
    chart!.clear()
    return
  }
  const isRoll = compareForm.value.metric === 'roll'
  const realY = isRoll ? apiSeries.value.roll : apiSeries.value.pitch
  const realPairs = times.map((t, i) => [times[i], realY[i]])

  // 预测曲线：使用外部传入的 predicted，按接口时间范围过滤；若无 ts，按索引对齐
  const predSrc = props.predicted?.[compareForm.value.metric]
  let predPairs: Array<[number, number]> = []
  if (predSrc && Array.isArray(predSrc.y) && predSrc.y.length) {
    if (Array.isArray(predSrc.ts) && predSrc.ts.length === predSrc.y.length) {
      const t0 = times[0], t1 = times[times.length - 1]
      for (let i = 0; i < predSrc.y.length; i++) {
        const tt = toEpoch(predSrc.ts[i])
        if (tt && tt >= t0 && tt <= t1) predPairs.push([tt, Number(predSrc.y[i])])
      }
    } else {
      // 无 ts 时按索引对齐到接口时间轴
      predPairs = times.map((tt, i) => [tt, Number(predSrc.y[Math.min(i, predSrc.y.length - 1)])])
    }
  }

  const nameMap: Record<'roll' | 'pitch', string> = {roll: '横摇', pitch: '纵摇'}
  chart!.setOption({
    backgroundColor: 'transparent',
    grid: {left: 40, right: 20, top: 60, bottom: 40},
    tooltip: {trigger: 'axis'},
    legend: {
      bottom: 0,
      textStyle: {color: '#fff'},
      data: ['船舶综合导航系统记录', '船舶姿态预测结果']
    },
    xAxis: {
      type: 'time',
      axisLine: {lineStyle: {color: 'rgba(255,255,255,0.4)'}},
      axisLabel: {color: '#cfe3ff'}
    },
    yAxis: {
      type: 'value',
      name: nameMap[compareForm.value.metric],
      nameTextStyle: {color: '#cfe3ff'},
      axisLine: {lineStyle: {color: 'rgba(255,255,255,0.4)'}},
      axisLabel: {color: '#cfe3ff'},
      splitLine: {lineStyle: {color: 'rgba(255,255,255,0.15)'}}
    },
    series: [
      {name: '船舶综合导航系统记录', type: 'line', showSymbol: true, data: realPairs},
      {name: '船舶姿态预测结果', type: 'line', showSymbol: false, data: predPairs}
    ]
  })
}

const compareForm = ref<{ range: [string, string] | []; metric: 'roll' | 'pitch' }>({
  range: [],
  metric: 'roll'
})

function onSelectionChange(selection: any[]) {
  selectedId.value = selection[0]?.dbname ?? ''
  selectedRow.value = selection[0] ?? null
}

function onSelect(selection: any[], row: any) {
  const nowSelected = selection.some(r => r.id === row.id)
  if (!tableRef.value) return
  tableRef.value.clearSelection()
  if (nowSelected) {
    tableRef.value.toggleRowSelection(row, true)
    selectedRow.value = row
    selectedId.value = row.dbname
  } else {
    selectedRow.value = null
    selectedId.value = ''
  }
}

async function onSearch() {
  if (!filters.value.name) {
    return ElMessage({type: 'warning', message: '请输入文件名!'});
  }
  try {
    const res = await getShipDataRecord(filters.value)
    dataList.value = res.list
    total = res.total
  } catch (err) {

  }
}

function onPageChange(p: number) {
  filters.value.page = p
  onSearch()
}

function onCancel() {
  innerVisible.value = false
  emits('cancel')
}

async function onCompare() {
  if (!selectedId.value) {
    return ElMessage({type: 'warning', message: '请先选择一条记录！'})
  }
  compareForm.value.metric = 'roll'
  const st = selectedRow.value?.stime || ''
  const et = selectedRow.value?.etime || ''
  compareForm.value.range = st && et ? [st, et] as [string, string] : []
  compareVisible.value = true
}

async function fetchCompareAndRender() {
  if (!compareForm.value.range.length) return
  try {
    compareLoading.value = true
    const {data} = await getShipDataCompare({
      name: selectedId.value,
      stime: compareForm.value.range[0],
      etime: compareForm.value.range[1]
    })
    const list = Array.isArray(data) ? data : []
    const times = list.map((d: any) => toEpoch(d.ts)).filter(Boolean)

    // 抽取 roll/pitch 数据（无需二次请求）
    const pick = (row: any, keys: string[], fallback = 0) => {
      for (const k of keys) {
        if (row[k] !== undefined && row[k] !== null) return Number(row[k])
      }
      return fallback
    }
    const roll = list.map((d: any) => d.rolling)
    const pitch = list.map((d: any) => d.pitching)

    apiSeries.value = {times, roll, pitch}
    renderChart()
  } catch (err) {
    ElMessage({type: 'error', message: '获取对比数据失败'})
  } finally {
    compareLoading.value = false
  }
}

function nextTickInitChart() {
  if (!chartRef.value) return
  if (!chart) {
    chart = echarts.init(chartRef.value)
    window.addEventListener('resize', handleResize)
  }
}

function handleResize() {
  chart?.resize()
}

watch(() => compareForm.value.range, () => {
  if (compareVisible.value) fetchCompareAndRender()
})

watch(() => compareForm.value.metric, () => {
  if (compareVisible.value) renderChart()
})

watch(compareVisible, (v) => {
  if (v) nextTickInitChart();
})

const compareTitle = computed(() => {
  if (!selectedRow.value) return ''
  const name = selectedRow.value?.name || selectedRow.value?.dbname || ''
  const st = selectedRow.value?.stime || ''
  const et = selectedRow.value?.etime || ''
  return `对比实际船舶记录：${name}， ${st} 到 ${et}`
})

watch(() => dataList.value, () => {
  selectedId.value = ''
  selectedRow.value = null
  if (tableRef.value) tableRef.value.clearSelection()
})
</script>

<template>
  <el-dialog
      v-model="innerVisible"
      class="data-compare-dialog"
      :show-close="true"
      width="1200px"
      align-center
      title="选择船舶综合导航系统记录"
  >
    <!-- 筛选行 -->
    <div class="filter-row">
      <el-input v-model.trim="filters.name" placeholder="文件名称" clearable class="filter-item"/>
      <el-button type="primary" class="filter-search" @click="onSearch">搜索</el-button>
    </div>

    <!-- 表格 -->
    <el-table
        ref="tableRef"
        :data="dataList"
        height="360"
        class="compare-table"
        header-row-class-name="compare-th"
        @selection-change="onSelectionChange"
        @select="onSelect"
    >
      <el-table-column
          type="selection"
          width="80"
          align="center"
          :selectable="selectableFn"
      />
      <el-table-column label="文件名称" prop="dbname" min-width="180"/>
      <el-table-column label="舰船类型" prop="type" min-width="120"/>
      <el-table-column label="时间跨度" min-width="260">
        <template #default="{ row }">
          {{ row.stime }}
          <span class="dash">—</span>
          {{ row.etime }}
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination-wrap">
      <el-pagination
          background
          layout="prev, pager, next"
          :current-page="filters.page"
          :page-size="filters.length"
          :total="total"
          @current-change="onPageChange"
      />
    </div>

    <!-- 底部按钮 -->
    <template #footer>
      <div class="footer-btns">
        <el-button @click="onCancel">取消</el-button>
        <el-button type="primary" @click="onCompare">对比</el-button>
      </div>
    </template>

    <!-- 对比弹窗 -->
    <el-dialog
        v-model="compareVisible"
        width="1100px"
        align-center
        class="attitude-compare-dialog"
        :show-close="true"
        title="姿态对比分析"
    >
      <div class="compare-header-line">{{ compareTitle }}</div>

      <div class="metric-row">
        <el-form :inline="true" :model="compareForm">
          <el-form-item label="对比时段">
            <el-date-picker
                v-model="compareForm.range"
                type="datetimerange"
                value-format="YYYY-MM-DD HH:mm:ss"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                style="width: 420px"
            />
          </el-form-item>
          <el-form-item label="对比数据项">
            <el-select v-model="compareForm.metric" style="width: 160px">
              <el-option v-for="o in metricOptions" :key="o.value" :label="o.label" :value="o.value"/>
            </el-select>
          </el-form-item>
        </el-form>
      </div>

      <div class="chart-wrap" v-loading="compareLoading">
        <div ref="chartRef" class="chart-box"/>
      </div>
    </el-dialog>
  </el-dialog>
</template>

<style scoped lang="less">
.el-table {
  background-color: transparent;
}

:deep(.el-table__header) {
  .el-table-column--selection {
    .cell {
      display: none !important;
    }
  }
}


/* 淡蓝色分割线网格 */
.compare-table {

  /* 外框：上、左，避免双线叠色 */
  :deep(.el-table__inner-wrapper) {
    border: 1px solid rgba(120, 180, 255, 0.35);
  }
  /* 每个单元格：右、下边框 */
  :deep(.el-table__cell) {
    border-right: 1px solid rgba(120, 180, 255, 0.35) !important;
    border-bottom: 1px solid rgba(120, 180, 255, 0.35) !important;
    background-color: transparent !important;
  }
  /* 表头底部分割线 */
  :deep(.el-table__header th) {
    border-bottom: 1px solid rgba(120, 180, 255, 0.35) !important;
    background: transparent !important; /* 头部透明 */
    color: #fff;
  }
  /* 行背景透明（避免深底遮住地图） */
  :deep(.el-table__row) {
    background: transparent !important;
  }
}

/* 关闭 Element Plus 默认白色边框伪元素，避免叠色 */
:deep(.el-table__inner-wrapper)::before,
:deep(.el-table__inner-wrapper)::after,
:deep(.el-table--border::before),
:deep(.el-table--border::after),
:deep(.el-table__border-left-patch) {
  display: none !important;
}

/* 时间跨度列的两行样式 */
.time-span { display: flex; flex-direction: column; align-items: center; line-height: 1.6; }
.time-span .t { color: #cfe3ff; }

</style>

<style lang="less">
:deep(.el-table__header .el-table-column--selection) {
  .cell {
    display: none !important;
  }
}

.data-compare-dialog, .attitude-compare-dialog {
  background: linear-gradient(180deg, rgba(0, 39, 97, 0.89) 0%, rgba(25, 36, 57, 0.92) 100%) !important;

  .el-dialog__title {
    color: #FFFFFF;
  }

  .el-form-item__label {
    color: #FFFFFF;
  }

  .el-table {
    .el-table__header th {
      background: transparent !important;
      border-bottom: none !important;
    }

    tr {
      background-color: transparent !important;
    }

    .is-horizontal {
      display: none!important;
    }

    .cell {
      color: #fff!important;
    }

  }

}

.data-compare-dialog :deep(.el-dialog__body) {
  padding-top: 12px;
}

.filter-row {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-bottom: 12px;

  .filter-item {
    width: 220px;
  }

  .filter-search {
    margin-left: 6px;
  }
}


.pagination-wrap {
  display: flex;
  justify-content: center;
  padding: 14px 0 6px;
}

.period-wrap {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0 0;

  .period-title {
    color: #fff;
    font-weight: 600;
    margin-right: 12px;
  }

  .dt {
    width: 280px;
  }

  .to {
    color: #fff;
    padding: 0 8px;
  }
}

.footer-btns {
  text-align: right;
}


.attitude-compare-dialog :deep(.el-dialog__body) {
  padding-top: 8px;
}

.compare-header-line {
  color: #fff;
  margin-bottom: 8px;
  font-size: 16px;
}

.metric-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}

.metric-row .label {
  color: #fff;
}

.chart-wrap {
  height: 520px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.chart-box {
  width: 100%;
  height: 480px;
  background: rgba(0, 0, 0, 0.15);
  border-radius: 4px;
}
</style>
